2.3 事件详解

添加命令

  • 无参数
import tkinter as tk

def callback():
    print("被点击了")

root = tk.Tk()
tk.Button(root, text='单击', command=callback).pack()

root.mainloop()
  • 有参数
import tkinter as tk

def callback(args):
    print("被点击了", args)

root = tk.Tk()
tk.Button(root, text='单击', command=lambda: callback("按钮")).pack()

root.mainloop()

如不想使用lambda表达式

import tkinter as tk

class Command:
    def __init__(self, func, *args):
        self.func = func
        self.args = args

    def __call__(self):
        self.func(*self.args)


def callback(args):
    print("被点击了", args)


root = tk.Tk()
tk.Button(root, text='单击', command=Command(callback, "按钮")).pack()

root.mainloop()

命令绑定的缺陷:

  • 只有Button和一小部分控件支持
  • 功能单一。命令只能绑定到鼠标左键单击和空格键点击事件,无法实现焦点、鼠标滚轮、快捷键响应等等丰富的交互情况

事件与绑定

所谓事件,就是在用户按下一个键或点击鼠标时,应用程序需要做出的反应。简单说就是对外部刺激做出的反应。

当窗口小控件中注册的事件发生时,会回调关联的处理函数,并将事件对象的实例作为参数传递到这个处理函数中。

事件参数文档

事件类型文档

鼠标事件

import tkinter as tk

root = tk.Tk()
tk.Label(root, text='单击').pack()


def callback(event):
    print("EventType=", event.type)
    print("Num=", event.num)


frame = tk.Frame(root, bg='khaki', width=100, height=80)
frame.bind("<Button-1>", callback)
frame.pack()

root.mainloop()

常用的几个鼠标事件

  • <Button-1>:鼠标左击事件
  • <Button-2>:鼠标滚轮点击
  • <Button-3>:鼠标右击事件
  • <Double-Button-1>:鼠标左双击事件
  • <Triple-Button-1>:鼠标左三击事件

关于事件回调传参 之前的命令回调我们都是通过lambda表达式传参,这里的事件回调也一样,只是稍微有一点区别

# 修改回调函数,添加a、b两个参数
def callback(event, a, b):
    print(a, b)
    print("EventType=", event.type)

# 注册回调时,在lambda表示中需要定义event参数
frame.bind("<Button-1>", lambda event: callback(event, 1, 2))

键盘事件

键名文档

import tkinter as tk

root = tk.Tk()
tk.Label(root, text='按键').pack()


def callback(event):
    print("EventType=", event.type)
    print("keysym=", event.keysym)


frame = tk.Frame(root, bg='khaki', width=100, height=80)
frame.pack()
root.bind("<KeyPress-a>", callback)  # a 键
root.bind("<KeyPress-F1>", callback)  # F1 键
root.bind("<Control-Alt-a>", callback)  # Ctrl + Alt + a 键

root.mainloop()

事件属性(Event类)

  • char 键盘事件,按键的字符
  • delta鼠标滚动事件,鼠标滚动的距离
  • heightwidth 仅用于Configure事件,即当控件形状发生变化之后的宽度和高度.相当于SizeChanged事件
  • keycode 键盘事件,按键码
  • keysymkeysym_num 按键事件
  • num 鼠标事件,鼠标按键码,1为左键,2为中建,3为右键
  • serial 相当于Event的ID
  • state 用来表示修饰键的状态,即ctrl,shift,alt等修饰键的状态.
  • time 事件发生的时间
  • type 事件的类型
  • widget 事件源控件
  • xyx_rooty_root 鼠标事件中鼠标的位置。x_root、·y_root`为绝对坐标,x,y为相对坐标。

绑定级别

事件有三种绑定级别,实际开发中选择合适的一种即可

  1. 实例绑定。将事件绑定到一个特定的控件实例上。如上述代码中的鼠标事件绑定到Frame实例上

    frame.bind("<Button-1>", callback)
    
  2. 类级绑定。可以将事件绑定到类的所有窗口小控件上。典型使用如下,所有Entry控件都将绑定到事件,该事件将调用名为paste的函数,类级绑定须慎用,以免造成不可预知的问题!

    my_entry.bind_class('Entry''<Control-V>',paste)
    
  3. 应用程序级绑定。只要应用程序的任何一个窗口处于焦点,事件发生时回调函数都会被调用。

    root.bind_all('<F1>',show_help)
    

    只要应用程序处于焦点,按F1键将始终触发 show_help函数回调

取消绑定

事件被注册后,是可以取消的,三种级别绑定的取消方法如下

entry.unbind('<Alt-Shift-5>')
root.unbind_all('<F1>')
root.unbind_class('Entry', '<KeyPress-Del>')

手动模拟事件

有时候我们需要用代码模拟生成一个事件,发送给监听者,而不是通过操作事件源产生事件

tkinter中所有的widget都包含一个公共方法event_generate,这个方法就是用来产生相应的事件的

event_generate("<<Copy>>")

要想查看这些内置的事件,需要查看Tk/tcl的文档,tkinter只是对Tk/tcl的封装,因此tkinter的文档并不是非常全面

Tk 事件文档

results matching ""

    No results matching ""